home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
MATH
/
PASCMP
/
PASCMPLX.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-06-29
|
8KB
|
227 lines
{ Complex mathematics unit for Borland Pascal }
{ (c)1994 by Alex Klimovitski }
{ *PasCmplx works with coprocessors 80287 and higher. }
{ *PasCmplx determines the presence of 80387 and uses its fast instructions. }
{ *See PASCMPLX.ASM for details how to change the unit for using with 8087. }
{ *Call CInit BEFORE using any routines from this unit except CCeck87. }
{ *If CInit returns non-zero, don't call any other routines except CCeck87. }
{ *You can directly assign complex variables, for example: }
{ }
{ var Z, P: Complex; }
{ Z := Cmplx(3.0, -2.0); }
{ P := Z; }
{ }
{ *Don't use real constants and variables for complex operations, for example:}
{ }
{ var Z, P: Complex; }
{ WRONG1: P := Z + 5.0; }
{ WRONG2: P := CAdd(Z, 5.0); }
{ CORRECT: P := CAdd(Z, Cmplx(5.0, 0)); }
{ }
{ As 1 and i (or j) for complex operations use also C1 and Ci (or Cj): }
{ }
{ WRONG: Z := CAdd(Z, 1); }
{ CORRECT: Z := CAdd(Z, C1); }
{ }
{ However, you can use real 0 for complex operations: }
{ }
{ CORRECT: P := CPow(Z, 0.0) }
{ }
{ *Functions CSinR, CCosR are much faster than standard functions Sin and Cos }
{ on systems with 80387 and higher. Function CSinCosR calculates both sine }
{ and cosine approx. twice as fast as CSinR and CSosR (on 80387). }
{ *PasCmplx doesn't initiate any exceptions. In case of wrong arguments (for }
{ example, division by zero) special 80x87 values "NAN" (not a number) or }
{ "+INF", "-INF" (infinity) are returned. Use CCheck, CCheckR functions to }
{ check quickly complex and real values. Use CTest, CTestR to obtain }
{ detailed information. }
{ *See PASCMPLX.ASM for details, CMPLXTES.PAS, PASFFT.PAS for examples. }
unit PasCmplx;
{$N+}
{$G+}
interface
type
Complex = Double;
var
C1: Complex; {complex 1}
Cj: Complex; {complex j ... or, if it is more convenient, ...}
Ci: Complex absolute Cj; {complex i}
const
{80x87 register state codes reported by CTest and CTestR}
C87ZerM = 0; {- 0}
C87ZerP = 1; {+ 0}
C87NorM = 2; {normalized < 0}
C87NorP = 3; {normalized > 0}
C87Ok = 3; {all values > 3 indicate error}
C87InfM = 4; {- infinity}
C87InfP = 5; {+ infinity}
C87UnnM = 6; {- unnormalized}
C87UnnP = 7; {+ unnormalized}
C87DenM = 8; {- denormalized}
C87DenP = 9; {+ denormalized}
C87NanM = 10; {- not-a-number}
C87NanP = 11; {+ not-a-number}
C87Empt = 12; {empty}
function CTest87: Integer;
{checks numeric coprocessor}
{returns 80x87 flag: 0=none, 1=8087, 2=80287, 3=80387 and higher}
function CInit: Integer;
{initializes complex math unit}
{returns zero if Ok, non-zero else}
function Cmplx(A, B: Double): Complex;
{makes complex from a and b}
{returns a + i * b}
function CReal(Z: Complex): Double;
{real part from z = a + i * b}
{returns a}
function CImag(Z: Complex): Double;
{imaginary part from z = a + i * b}
{returns b}
function Conjug(Z: Complex): Complex;
{conjugate complex for z = a + i * b}
{returns a - i * b}
function CAdd(Z, P: Complex): Complex;
{adds z = a + i * b and p = c + i * d}
{returns z + p}
function CSub(Z, P: Complex): Complex;
{subtracts p = c + i * d from z = a + i * b}
{returns z - p}
function CMul(Z, P: Complex): Complex;
{multiplies z = a + i * b and p = c + i * d}
{returns z * p}
function CDiv(Z, P: Complex): Complex;
{divides z = a + i * b by p = c + i * d}
{returns z / p}
function C1Z(Z: Complex): Complex;
{divides 1 by z = a + i * b}
{returns 1 / z}
function CAbs(Z: Complex): Double;
{absolute value of complex z = a + i * b}
{returns abs(z) = a^2 + b^2}
function CArg(Z: Complex): Double;
{argument of complex z = a + i * b}
{returns arg(z)}
{NOTE: in common case arg(z) <> arctan(b/a) !}
function CExp(Z: Complex): Complex;
{exponential of complex z}
{returns e^z = e^a * (cos(b) + i * sin(b))}
function CLn(Z: Complex): Complex;
{natural logarithm of complex z}
{returns ln(z) = ln(abs(z)) + i * arg(z)}
{NOTE: in common case ln(e^z) <> z !}
function CPow(Z, P: Complex): Complex;
{complex z in complex power p}
{returns z^p = e^(p * ln(z))}
function CRPow(Z: Complex; R: Double): Complex;
{complex z in real power r; works faster than CPow}
{returns z^r = abs(z)^r * (cos(r*arg(z)) + i * sin(r*arg(z)))}
function CIPow(Z: Complex; N: Integer): Complex;
{complex z in integer power n; works faster than CRPow}
{returns z^n}
function CSinR(R: Double): Double;
{sine of real r; on 80387 uses special instruction}
{returns sin(r)}
function CCosR(R: Double): Double;
{sine of real r; on 80387 uses special instruction}
{returns cos(r)}
procedure CSinCosR(R: Double; var S, C: Double);
{sine and cosine of real r; on 80387 uses special instruction}
{s := sin(r); c := cos(r)}
function CTest(Z: Complex): Word;
{tests complex z}
{returns state of real part in low byte, state of imag. part in high byte}
{the state is one of 80x87 register state flags above}
function CTestR(R: Double): Word;
{tests real r}
{returns state of real r in low byte, high byte = 0}
{the state is one of 80x87 register state flags above}
function CCheck(Z: Complex): Word;
{checks quickly complex z}
{returns nonzero if real or imag. part invalid (not a zero and
not a normalized number), zero if both are Ok}
function CCheckR(R: Double): Word;
{checks quickly real r}
{returns nonzero if real r invalid (not a zero and not a normalized
number), zero if it is Ok}
implementation
{$L PASCMPLX}
function CTest87; external;
function CInit; external;
function Cmplx; external;
function CReal; external;
function CImag; external;
function Conjug; external;
function CAdd; external;
function CSub; external;
function CMul; external;
function CDiv; external;
function C1Z; external;
function CAbs; external;
function CArg; external;
function CExp; external;
function CLn; external;
function CPow; external;
function CRPow; external;
function CIPow; external;
function CSinR; external;
function CCosR; external;
procedure CSinCosR; external;
function CTest; external;
function CTestR; external;
function CCheck; external;
function CCheckR; external;
{The following functions are used internally on 80287 systems}
{I'm sorry I was too lazy to write my own Sin/Cos for 80287;}
{if you have your own ones place them here!}
function Sin(D: Double): Double;
begin
Sin := System.Sin(D);
end;
function Cos(D: Double): Double;
begin
Cos := System.Cos(D);
end;
begin
CInit;
end.